
package combat.dudes.operator;

import gnu.cajo.invoke.Remote;
import gnu.cajo.utils.extra.TransparentItemProxy;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;

import combat.dudes.protocol.data.RemoteList;
import combat.dudes.protocol.interfaces.SimulationInt;
import combat.dudes.protocol.interfaces.TeamInt;
import combat.dudes.protocol.interfaces.UserInt;
import combat.dudes.protocol.interfaces.VehicleInt;
import combat.dudes.protocol.types.VehicleType;


/**
 * The core of the operator application
 * @author Erik Meijer
 */

public class Core {

	static SimulationInt sim;

	static RemoteList remoteUsers = new RemoteList();
	static RemoteList remoteTeams = new RemoteList();
	static RemoteList remoteVehicles = new RemoteList();

	static ArrayList<UserInt> users = new ArrayList<UserInt>();
	static ArrayList<TeamInt> teams = new ArrayList<TeamInt>();
	static ArrayList<VehicleInt> vehicles = new ArrayList<VehicleInt>();

	static String connectionString = "";

	static enum commandList {
		UNKNOWN, EXIT, HELP, TEAMS, VEHICLES, START, STOP, PAUSE, RESUME, SIMSPEED, TEAMSTATUS, USERSTATUS, VEHICLESTATUS, MOVEUSER, MAKEVEHICLE, ASSIGNVEHICLE, QUICKVEHICLE, QUICKASSIGN, CLEARVEHICLE, LOCKVEHICLE;
	}


	static void connect() throws Exception {

		connectionString = OperatorCommands.handleInput();

		if(connectionString.equals("local")) {
			connectionString = "localhost";
		} else if(connectionString.equals("exit"))
			OperatorApp.isRunning = false;

		try {
			sim = (SimulationInt) TransparentItemProxy.getItem("//" + connectionString + ":28000/Simulation", new Class[] { SimulationInt.class });
			OperatorApp.isConnected = true;
			System.out.println("Connection established! Please type \"help\" for a list of available commands.");

		} catch(Exception e) {
			System.out.println("Connection failed (" + e + ")\nPlease enter IP address.\nOr type \"local\" to connect via localhost.");
		}
	}

	static boolean inputChecker(String input) {
		if(!input.equals("") && input != null) {
			return true;
		} else return false;
	}

	static boolean tokenChecker(int index, String[] tokens) {
		switch(index) {
			case 2:
				if(tokens.length == 2)
					return true;
			case 3:
				if(tokens.length == 3)
					return true;
			case 4:
				if(tokens.length == 4)
					return true;
			case 6:
				if(tokens.length == 6)
					return true;
		}
		return false;
	}

	static boolean isInt(String Token) {
		try {
			Integer.parseInt(Token);
		} catch(NumberFormatException nfe) {
			return false;
		}
		return true;
	}

	static boolean isDouble(String Token) {

		try {
			Double.parseDouble(Token);
		} catch(NumberFormatException nfe) {
			return false;
		}
		return true;
	}

	static TeamInt teamChecker(int teamID) {
		for(TeamInt team : Core.teams)
			if(team.getTeamID() == teamID)
				return team;
		return null;
	}

	static UserInt userChecker(int userID) {
		for(UserInt user : Core.users)
			if(user.getUserID() == userID)
				return user;
		return null;
	}

	static VehicleInt vehicleChecker(int teamID, int vehicleID) {
		int i = 0;

		for(TeamInt team : Core.teams)
			if(team.getTeamID() == teamID)
				for(VehicleInt vehicle : team.getVehicles())
					if(i++ == vehicleID)
						return vehicle;
		return null;
	}

	static VehicleType vehicleTypeChecker(String type) { // TODO
		for(VehicleType vehicletype : VehicleType.values())
			if(type.toUpperCase().equals(vehicletype.toString()))
				return vehicletype;
		return null;
	}

	static commandList commandChecker(String input) {
		for(commandList command : combat.dudes.operator.Core.commandList.values()) {
			if(command.toString().equals(input.toUpperCase()))
				return command;
		}
		return commandList.UNKNOWN;
	}

	static TeamInt userTeamFinder(int userID) {
		for(TeamInt team : Core.teams)
			for(UserInt user : team.getUsers())
				if(user.getUserID() == userID)
					return team;
		return null;
	}

	static double doubleParser(String token, String[] tokens) throws ParseException {
		NumberFormat fmt = NumberFormat.getInstance();
		Number number = fmt.parse(tokens[1]);
		return number.doubleValue();
	}

	static void makeTeamList() throws Exception {
		teams.clear();
		remoteTeams = (RemoteList) Remote.invoke(sim, "getTeams_Remote", null);
		for(Object teamRemote : remoteTeams)
			teams.add((TeamInt) TransparentItemProxy.getItem(remoteTeams.get(remoteTeams.indexOf(teamRemote)), new Class[] { TeamInt.class }));
	}

	static void makeUserList() throws Exception {
		users.clear();
		for(Object teamRemote : remoteTeams) {
			remoteUsers = (RemoteList) Remote.invoke(teamRemote, "getUsers_Remote", null);
			for(Object userRemote : remoteUsers)
				users.add((UserInt) TransparentItemProxy.getItem(userRemote, new Class[] { UserInt.class }));
		}
	}

	static void makeVehicleList() throws Exception {
		vehicles.clear();
		for(Object teamRemote : remoteTeams) {
			remoteVehicles = (RemoteList) Remote.invoke(teamRemote, "getVehicles_Remote", null);
			for(Object vehicleRemote : remoteVehicles)
				vehicles.add((VehicleInt) TransparentItemProxy.getItem(vehicleRemote, new Class[] { VehicleInt.class }));
		}
	}

}
